package com.jinglan.jybsh.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.jinglan.framework.common.OrderState;
import com.jinglan.framework.util.date.DateUtil;
import com.jinglan.framework.util.httpclient.HttpHelper;
import com.jinglan.framework.util.md5.MD5Util;
import com.jinglan.framework.util.string.StringUtil;
import com.jinglan.qcoin.center.pojo.QcoinChannelOrder;

@Service
public class JybShService implements InitializingBean {

	@Value("${orderUrl}")
	private String orderUrl;// 下单地址
	@Value("${queryOrderUrl}")
	private String queryOrderUrl;// 查单地址
	@Value("${businessType}")
	private int businessType;// 业务类型
	@Value("${merAccount}")
	String merAccount;//商户号
	@Value("${merKey}")
	private String Key;// 商户密钥
	private long rechargeNum = 1;// 充值数量
	private long rechargeValue;
	private Integer requestTimeOut = 18000;// 请求超时时间
	private String encoding = "UTF-8";
	@Value("${notifyUrl}")
	private String notifyUrl;
	private Logger logger = LoggerFactory.getLogger(JybShService.class);

	// q币充值
	public QcoinChannelOrder placeOrder(String msgHead,String fixip, String channelOrderNo, long rechargeAmount, String qq, String orderNo,
			String ip) {
		QcoinChannelOrder rstChannelOrder = getHandlingOrder(channelOrderNo);
		String merOrderTime = DateUtil.formate(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss");
		rechargeValue = rechargeAmount;

		JSONObject map = new JSONObject();
		map.put("merAccount", merAccount);
		map.put("merUserAccount", "");
		map.put("businessType", businessType + "");
		map.put("merOrderNo", channelOrderNo);
		map.put("merOrderTime", merOrderTime);
		map.put("extendAccount", "");
		map.put("rechargeAccount", qq);
		map.put("rechargeValue", rechargeValue + "");
		map.put("rechargeNum", rechargeNum + "");
		map.put("extendParam", "");
		map.put("attach", "");
		map.put("customerIp", ip);
		map.put("notifyUrl", notifyUrl);
		// 组织签名数据
		String data = map.toString();
		logger.info("签名原串:" + data);
		String sign = MD5Util.encrypt("data=" + data + "&key=" + Key, encoding).toLowerCase();
		Map<String, String> paramsMap = new HashMap<String, String>();
		paramsMap.put("data", data);// data数据
		paramsMap.put("sign", sign);// sign数据
		try {
			String postResult = HttpHelper.executePostString(orderUrl, paramsMap, "UTF-8", requestTimeOut);
			logger.info(msgHead + "原始数据:" + postResult);
			if (postResult == null || postResult.contains("<html")) {
				return rstChannelOrder;
			} // 正常处理
			logger.info(msgHead + "上游返回原始数据：" + postResult);
			rstChannelOrder = getResultOrder( msgHead, channelOrderNo, postResult);
			return rstChannelOrder;

		} catch (IOException e) {
			logger.info(msgHead + "接口下单处理异常", e);
		}
		return rstChannelOrder;

	}

	// 订单处理返回的
	private QcoinChannelOrder getResultOrder( String msgHead, String channelOrderNo,
			String postResult) {
		QcoinChannelOrder rstChannelOrder = new QcoinChannelOrder();
		rstChannelOrder.setOrderState(OrderState.handling.getState());
		rstChannelOrder.setOrderStateDesc(OrderState.handling.getStateDesc());		
		rstChannelOrder.setChannelResult(postResult);
		// 对上游参数进行解析
		JSONObject rspObj = JSONObject.parseObject(postResult);
		// 返回状态码
		String code = rspObj.getString("resultCode");
		// 返回订单的状态
		OrderState thisOrderState = getOrderState(msgHead, code);
		rstChannelOrder.setChannelState(code);
		rstChannelOrder.setOrderState(thisOrderState.getState());
		rstChannelOrder.setChannelOrderNo(rspObj.getString("merOrderNo"));//渠道订单号
		rstChannelOrder.setPartnerOrderNo(rspObj.getString("orderNo"));//上游订单号
		rstChannelOrder.setOrderStateDesc(thisOrderState.getStateDesc());
		return rstChannelOrder;
	}

	// 处理状态码
	private OrderState getOrderState(String msgHead, String code) {
		if (StringUtil.isNull(code)) {
			logger.info(msgHead + "操作状态为null无法判断订单状态");
			return OrderState.handling;
		}
		// 判断操作码
		switch (code) {
		case "0":// 成功
			logger.info(msgHead + "操作状态返回[0:订单提交成功 ]");
			return OrderState.handling;
		case "1":// 参数缺少或错误
			logger.info(msgHead + "操作状态返回[1:参数缺少或错误]");
			return OrderState.fail;
		case "2":// 商户信息校验失败
			logger.info(msgHead + "操作状态返回[2:商户信息校验失败]");
			return OrderState.fail;
		case "3":// 系统维护中
			logger.info(msgHead + "操作状态返回[3:系统维护中]");
			return OrderState.fail;
		case "4":// 商户信息不可用
			logger.info(msgHead + "操作状态返回[4:商户信息不可用]");
			return OrderState.fail;	
		case "5":// 拒绝访问
			logger.info(msgHead + "操作状态返回[5:拒绝访问]");
			return OrderState.fail;	
		case "6":// 接单暂停，请稍后再试
			logger.info(msgHead + "操作状态返回[6:接单暂停，请稍后再试]");
			return OrderState.fail;
		case "7":// IP地址不合法
			logger.info(msgHead + "操作状态返回[7:IP地址不合法]");
			return OrderState.fail;
		case "8":// 签名信息校验失败
			logger.info(msgHead + "操作状态返回[8:签名信息校验失败]");
			return OrderState.fail;
		case "9":// 业务系统维护中
			logger.info(msgHead + "操作状态返回[9:业务系统维护中]");
			return OrderState.fail;
		case "10":// 请求过于频繁
			logger.info(msgHead + "操作状态返回[10:请求过于频繁]");
			return OrderState.fail;
		case "17":// 交易金额不合法
			logger.info(msgHead + "操作状态返回[17:交易金额不合法]");
			return OrderState.fail;
		case "18":// 充值账号不合法
			logger.info(msgHead + "操作状态返回[18:充值账号不合法]");
			return OrderState.fail;
		default:
			logger.info(msgHead + "操作状态返回[" + code + "]无法判断订单状态");
			break;
		}
		return OrderState.unsure;
	}

	// 查单
	public QcoinChannelOrder queryOrder(String msgHead, String qq,String channelOrderNo,String partnerOrderNo) {
		QcoinChannelOrder rstChannelOrder = getHandlingOrder(channelOrderNo);
		String Time = DateUtil.formate(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss");
		JSONObject map = new JSONObject();
		map.put("merAccount", merAccount);
		map.put("businessType", businessType + "");
		map.put("orderNo", partnerOrderNo);
		map.put("merOrderNo", channelOrderNo);
		map.put("merRequestTime", Time);
		// 组织签名数据
		String data = map.toString();
		//计算签名
		String sign = MD5Util.encrypt("data=" + data + "&key=" + Key, encoding).toLowerCase();
		Map<String, String> paramsMap = new HashMap<String, String>();
		paramsMap.put("data", data);// data数据
		paramsMap.put("sign", sign);// sign数据
		try {
			String postResult = HttpHelper.executePostString(queryOrderUrl, paramsMap, "UTF-8", requestTimeOut);
			logger.info(msgHead + "原始数据:" + postResult);
			if (postResult == null || postResult.contains("<html")) {
				return rstChannelOrder;
			} // 正常处理
			logger.info(msgHead + "上游返回原始数据：" + postResult);
			rstChannelOrder = getQueryResultOrder(true, msgHead, channelOrderNo, postResult);
			return rstChannelOrder;

		} catch (IOException e) {

			e.printStackTrace();
		}
		return rstChannelOrder;
	}

	// 查询结果处理
	private QcoinChannelOrder getQueryResultOrder(boolean isOrder, String msgHead, String channelOrderNo,
			String postResult) {
		QcoinChannelOrder rstChannelOrder = new QcoinChannelOrder();
		rstChannelOrder.setChannelOrderNo(channelOrderNo);
		rstChannelOrder.setOrderState(OrderState.handling.getState());
		rstChannelOrder.setOrderStateDesc(OrderState.handling.getStateDesc());
		if (postResult == null) {
			rstChannelOrder.setChannelResult(isOrder ? "上游未返回下单响应数据" : "上游未返回查单响应数据");
			return rstChannelOrder;
		}
		rstChannelOrder.setChannelResult(postResult);
		// 对上游参数进行解析
		JSONObject rspObj = JSONObject.parseObject(postResult);
		// 返回状态码
		String code = rspObj.getString("resultCode");
		logger.info(msgHead + "结果码11：" + code);
		JSONObject jsondata=rspObj.getJSONObject("data");//取出data里面的值
		String orderAmount = jsondata.getString("orderAmount");
		logger.info(msgHead + "结果码222：" + code+"------"+orderAmount);
		// 返回订单的状态
		OrderState thisOrderState = getOrderQueryState(msgHead, code);
		rstChannelOrder.setChannelState(code);
		rstChannelOrder.setOrderState(thisOrderState.getState());
		rstChannelOrder.setOrderStateDesc(thisOrderState.getStateDesc());
		if (thisOrderState.getState() == OrderState.success.getState()) {
			rstChannelOrder.setSuccessAmount(Long.parseLong(orderAmount));
		} else if (thisOrderState.getState() == OrderState.fail.getState()) {
			rstChannelOrder.setSuccessAmount((long) 0);
		}
		return rstChannelOrder;
	}

	// 查询返回的订单状态
	private OrderState getOrderQueryState(String msgHead, String code) {
		if (StringUtil.isNull(code)) {
			logger.info(msgHead + "操作状态为null无法判断订单状态");
			return OrderState.handling;
		} else if ("-1".equals(code)) {
			logger.info(msgHead + "操作状态为-1 订单已取消");
			return OrderState.fail;
		} else if ("0".equals(code)) {
			logger.info(msgHead + "操作状态为0 订单初始化");
			return OrderState.handling;
		} else if ("20".equals(code)) {
			logger.info(msgHead + "操作状态为20 订单充值中");
			return OrderState.handling;
		} else if ("21".equals(code)) {
			logger.info(msgHead + "操作状态为21 充值待确认");
			return OrderState.unsure;
		} else if ("22".equals(code)) {
			logger.info(msgHead + "操作状态为22 充值部分成功");
			return OrderState.unsure;
		} else if ("23".equals(code)) {
			logger.info(msgHead + "操作状态为23 充值全部失败");
			return OrderState.fail;
		} else if ("24".equals(code)) {
			logger.info(msgHead + "操作状态为24 充值全部成功");
			return OrderState.success;
		} else {
			return OrderState.handling;
		}
	}

	private QcoinChannelOrder getHandlingOrder(String channelOrderNo) {
		QcoinChannelOrder rstChannelOrder = new QcoinChannelOrder();
		rstChannelOrder.setChannelOrderNo(channelOrderNo);
		rstChannelOrder.setOrderState(OrderState.handling.getState());
		rstChannelOrder.setOrderStateDesc(OrderState.handling.getStateDesc());
		return rstChannelOrder;
	}

	@Override
	public void afterPropertiesSet() throws Exception {

	}
}
